// 网络请求封装工具
// 支持uni-app多端开发

// 默认配置
const defaultConfig = {
  baseURL: '', // 基础URL，可在此设置API服务器地址
  timeout: 10000, // 请求超时时间
  header: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
}

// 请求状态码映射
const statusCodeMap = {
  200: '请求成功',
  201: '创建成功',
  204: '删除成功',
  400: '请求参数错误',
  401: '未授权，请重新登录',
  403: '拒绝访问',
  404: '请求资源不存在',
  500: '服务器内部错误',
  502: '网关错误',
  503: '服务不可用',
  504: '网关超时'
}

// 请求拦截器队列
const requestInterceptors = []
const responseInterceptors = []

// 正在进行的请求队列
const pendingRequests = new Map()

/**
 * 生成请求唯一标识
 */
function generateRequestKey(config) {
  const { url, method, data } = config
  return `${method}_${url}_${JSON.stringify(data || {})}`
}

/**
 * 取消重复请求
 */
function cancelDuplicateRequest(config) {
  const requestKey = generateRequestKey(config)
  
  if (pendingRequests.has(requestKey)) {
    // 取消之前的请求
    const previousRequest = pendingRequests.get(requestKey)
    previousRequest.abort && previousRequest.abort()
    pendingRequests.delete(requestKey)
  }
  
  return requestKey
}

/**
 * 显示加载提示
 */
function showLoading(config) {
  if (config.loading !== false) {
    uni.showLoading({
      title: config.loadingText || '加载中...',
      mask: true
    })
  }
}

/**
 * 隐藏加载提示
 */
function hideLoading(config) {
  if (config.loading !== false) {
    uni.hideLoading()
  }
}

/**
 * 显示错误提示
 */
function showError(message, config) {
  if (config.showError !== false) {
    uni.showToast({
      title: message,
      icon: 'none',
      duration: 2000
    })
  }
}

/**
 * 处理请求错误
 */
function handleRequestError(error, config) {
  hideLoading(config)
  
  let message = '网络请求失败'
  
  if (error.statusCode) {
    message = statusCodeMap[error.statusCode] || `请求失败(${error.statusCode})`
  } else if (error.errMsg) {
    if (error.errMsg.includes('timeout')) {
      message = '请求超时，请检查网络连接'
    } else if (error.errMsg.includes('fail')) {
      message = '网络连接失败，请检查网络设置'
    }
  }
  
  showError(message, config)
  
  return Promise.reject({
    ...error,
    message
  })
}

/**
 * 处理响应数据
 */
function handleResponse(response, config) {
  hideLoading(config)
  
  const { statusCode, data } = response
  
  // HTTP状态码检查
  if (statusCode >= 200 && statusCode < 300) {
    // 业务状态码检查（根据实际API调整）
    if (data && typeof data === 'object') {
      // 假设API返回格式为 { code: 200, data: {}, message: '' }
      if (data.code !== undefined) {
        if (data.code === 200 || data.code === 0) {
          return Promise.resolve(data.data !== undefined ? data.data : data)
        } else {
          // 业务错误
          const message = data.message || data.msg || '请求失败'
          showError(message, config)
          return Promise.reject({
            code: data.code,
            message,
            data: data.data
          })
        }
      }
    }
    return Promise.resolve(data)
  } else {
    return handleRequestError(response, config)
  }
}

/**
 * 核心请求方法
 */
function request(config) {
  // 合并配置
  const finalConfig = {
    ...defaultConfig,
    ...config,
    header: {
      ...defaultConfig.header,
      ...config.header
    }
  }
  
  // 处理URL
  if (finalConfig.baseURL && !finalConfig.url.startsWith('http')) {
    finalConfig.url = finalConfig.baseURL.replace(/\/$/, '') + '/' + finalConfig.url.replace(/^\//, '')
  }
  
  // 执行请求拦截器
  for (const interceptor of requestInterceptors) {
    try {
      const result = interceptor(finalConfig)
      if (result === false) {
        return Promise.reject(new Error('请求被拦截器取消'))
      }
      if (result && typeof result === 'object') {
        Object.assign(finalConfig, result)
      }
    } catch (error) {
      console.error('请求拦截器执行错误:', error)
    }
  }
  
  // 取消重复请求
  const requestKey = cancelDuplicateRequest(finalConfig)
  
  // 显示加载提示
  // 手动添加token到header中，因为uni.uploadFile不会自动应用请求拦截器
  const token = uni.getStorageSync('user-token')
  if (token) {
    finalConfig.header = finalConfig.header || {}
    finalConfig.header.Authorization = token
    console.log('✅ 上传请求已添加token:', token.substring(0, 20) + '...')
  } else {
    console.log('⚠️ 上传请求未添加token: 用户未登录或token不存在')
  }
  
  showLoading(finalConfig)
  
  // 创建请求Promise
  const requestPromise = new Promise((resolve, reject) => {
    const requestTask = uni.request({
      ...finalConfig,
      success: (response) => {
        // 执行响应拦截器
        let processedResponse = response
        for (const interceptor of responseInterceptors) {
          try {
            const result = interceptor(processedResponse, finalConfig)
            if (result) {
              processedResponse = result
            }
          } catch (error) {
            console.error('响应拦截器执行错误:', error)
          }
        }
        
        handleResponse(processedResponse, finalConfig)
          .then(resolve)
          .catch(reject)
      },
      fail: (error) => {
        handleRequestError(error, finalConfig)
          .catch(reject)
      },
      complete: () => {
        // 从队列中移除请求
        pendingRequests.delete(requestKey)
      }
    })
    
    // 将请求任务添加到队列
    pendingRequests.set(requestKey, requestTask)
  })
  
  return requestPromise
}

/**
 * HTTP请求类
 */
class Http {
  constructor(config = {}) {
    this.config = { ...defaultConfig, ...config }
  }
  
  // 设置基础URL
  setBaseURL(baseURL) {
    this.config.baseURL = baseURL
    return this
  }
  
  // 设置通用请求头
  setHeader(header) {
    this.config.header = { ...this.config.header, ...header }
    return this
  }
  
  // 设置超时时间
  setTimeout(timeout) {
    this.config.timeout = timeout
    return this
  }
  
  // 添加请求拦截器
  addRequestInterceptor(interceptor) {
    if (typeof interceptor === 'function') {
      requestInterceptors.push(interceptor)
    }
    return this
  }
  
  // 添加响应拦截器
  addResponseInterceptor(interceptor) {
    if (typeof interceptor === 'function') {
      responseInterceptors.push(interceptor)
    }
    return this
  }
  
  // 通用请求方法
  request(config) {
    return request({ ...this.config, ...config })
  }
  
  // GET请求
  get(url, params = {}, config = {}) {
    return this.request({
      url,
      method: 'GET',
      data: params,
      ...config
    })
  }
  
  // POST请求
  post(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'POST',
      data,
      ...config
    })
  }
  
  // PUT请求
  put(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'PUT',
      data,
      ...config
    })
  }
  
  // DELETE请求
  delete(url, data = {}, config = {}) {
    return this.request({
      url,
      method: 'DELETE',
      data,
      ...config
    })
  }
  
  // 上传文件
  upload(url, filePath, config = {}) {
    const finalConfig = {
      ...this.config,
      ...config,
      url: this.config.baseURL ? 
        this.config.baseURL.replace(/\/$/, '') + '/' + url.replace(/^\//, '') : 
        url
    }
    
    // 手动添加token到header中，因为uni.uploadFile不会自动应用请求拦截器
    const token = uni.getStorageSync('user-token')
    if (token) {
      finalConfig.header = finalConfig.header || {}
      finalConfig.header.Authorization = token
      console.log('✅ 上传请求已添加token:', token.substring(0, 20) + '...')
    } else {
      console.log('⚠️ 上传请求未添加token: 用户未登录或token不存在')
    }
    
    showLoading(finalConfig)
    
    return new Promise((resolve, reject) => {
      uni.uploadFile({
        ...finalConfig,
        filePath,
        name: config.name || 'file',
        success: (response) => {
          hideLoading(finalConfig)
          try {
            const data = typeof response.data === 'string' ? 
              JSON.parse(response.data) : 
              response.data
            resolve(data)
          } catch (error) {
            resolve(response.data)
          }
        },
        fail: (error) => {
          handleRequestError(error, finalConfig).catch(reject)
        }
      })
    })
  }
  
  // 下载文件
  download(url, config = {}) {
    const finalConfig = {
      ...this.config,
      ...config,
      url: this.config.baseURL ? 
        this.config.baseURL.replace(/\/$/, '') + '/' + url.replace(/^\//, '') : 
        url
    }
    
    // 手动添加token到header中，因为uni.uploadFile不会自动应用请求拦截器
    const token = uni.getStorageSync('user-token')
    if (token) {
      finalConfig.header = finalConfig.header || {}
      finalConfig.header.Authorization = token
      console.log('✅ 上传请求已添加token:', token.substring(0, 20) + '...')
    } else {
      console.log('⚠️ 上传请求未添加token: 用户未登录或token不存在')
    }
    
    showLoading(finalConfig)
    
    return new Promise((resolve, reject) => {
      uni.downloadFile({
        ...finalConfig,
        success: (response) => {
          hideLoading(finalConfig)
          if (response.statusCode === 200) {
            resolve(response.tempFilePath)
          } else {
            reject(response)
          }
        },
        fail: (error) => {
          handleRequestError(error, finalConfig).catch(reject)
        }
      })
    })
  }
  
  // 取消所有请求
  cancelAllRequests() {
    for (const [key, requestTask] of pendingRequests) {
      requestTask.abort && requestTask.abort()
      pendingRequests.delete(key)
    }
  }
}

// 创建默认实例
const http = new Http()

// 导出
export default http
export { Http }

// 便捷方法导出
export const get = (url, params, config) => http.get(url, params, config)
export const post = (url, data, config) => http.post(url, data, config)
export const put = (url, data, config) => http.put(url, data, config)
export const del = (url, data, config) => http.delete(url, data, config)
export const upload = (url, filePath, config) => http.upload(url, filePath, config)
export const download = (url, config) => http.download(url, config) 